using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Net;
using System.Net.Cache;
using System.IO;
using System.Globalization;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Web;
using System.Data.SqlClient;
using System.Data.SqlTypes;

namespace Microsoft.Samples.SqlServer
{
	public partial class ManuInstructions : Form
	{
		const string prettyXmlXsltFileName = "..\\..\\defaultss.xslt";
		const string instructionsXsltFileName = "..\\..\\ManuInstructions.xsl";

		public ManuInstructions()
		{
			InitializeComponent();
		}

		private static string GetSoapRequestXml(int productModelID)
		{
			return
			"<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>" +
			"  <soap:Body>" +
				"<GetManuInstructions xmlns='testns'>" +
				  "   <ProductModelID>" + productModelID + "</ProductModelID>" +
				"</GetManuInstructions>" +
			"  </soap:Body>" +
			"</soap:Envelope>";
		}

		private static Stream PostSoapRequest(string requestXml)
		{
			HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create("http://localhost/manuinstructions/");
			webRequest.Accept = "text/xml";
			webRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, "identity, gzip;q=0");
			webRequest.ContentType = "text/xml";
			webRequest.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
			webRequest.Headers.Add("SOAPAction", "");
			webRequest.Credentials = CredentialCache.DefaultCredentials;
			webRequest.Method = "POST";

			Stream webStream = webRequest.GetRequestStream();
			using (StreamWriter webWriter = new StreamWriter(webStream))
			{
				try
				{
					webWriter.Write(requestXml);
					webWriter.Flush();
				}
				finally
				{
				}
			}

			WebResponse response = webRequest.GetResponse();
			return response.GetResponseStream();
		}


		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
		private void ShowInstructionsButton_Click(object sender, EventArgs e)
		{
			try
			{
				int productModelID = int.Parse(ProductModelIDTextBox.Text,
					CultureInfo.InvariantCulture);
				String requestXML = GetSoapRequestXml(productModelID);
				using (Stream webResponseStream = PostSoapRequest(requestXML))
				{
					XslCompiledTransform xslt = new XslCompiledTransform(true);
					using (StreamReader xsltStreamReader = File.OpenText(instructionsXsltFileName))
					{
						using (XmlReader xsltXmlReader = XmlReader.Create(xsltStreamReader))
						{
							xslt.Load(xsltXmlReader);
						}
					}

					XPathDocument xmlResults = new XPathDocument(webResponseStream);
					XPathNavigator navigator = xmlResults.CreateNavigator();
					XmlNamespaceManager namespaces = new XmlNamespaceManager(navigator.NameTable);
					namespaces.AddNamespace("z", "http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions");

					XPathExpression expr = navigator.Compile("//z:root");
					expr.SetContext(namespaces);
					XPathNodeIterator iterator = navigator.Select(expr);
					if (iterator.Count == 0)
					{
						webBrowser1.DocumentText = string.Format(
							System.Globalization.CultureInfo.InvariantCulture,
							"<BODY>Product {0} not found.<BODY>",
							productModelID);
					}
					else
					{
						StringWriter resultStringWriter = new StringWriter(CultureInfo.InvariantCulture);
						XmlTextWriter resultXmlWriter = new XmlTextWriter(resultStringWriter);

						if (iterator.MoveNext())
						{
							string destinationPath = "about:blank";
							XPathNavigator diagNavigator = iterator.Current.SelectSingleNode("//z:step/z:diag", namespaces);
							if (diagNavigator != null)
							{
								string diagID = diagNavigator.Value;

								destinationPath = Path.ChangeExtension(Path.GetTempFileName(), ".svg");
								using (TextWriter destinationFile = File.CreateText(destinationPath))
								{
									using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.ConnectionString))
									{
										SqlCommand cmd = conn.CreateCommand();
										cmd.CommandText = "SELECT Diagram FROM Production.Illustration WHERE IllustrationID = @IllustrationID";
										cmd.Parameters.Add("@IllustrationID", SqlDbType.Int);
										cmd.Parameters[0].Value = int.Parse(diagID, System.Globalization.CultureInfo.InvariantCulture);

										conn.Open();
										SqlDataReader r = cmd.ExecuteReader();
										if (r != null && r.Read())
										{
											System.Xml.XmlReader reader = XmlReader.Create(new StringReader((String)r.GetValue(0)));

											XmlDocument doc = new XmlDocument();
											doc.Load(reader);
											XmlElement root = doc.DocumentElement;
											root.SetAttribute("viewbox", "0, 0, " + root.GetAttribute("width") + "," + root.GetAttribute("height"));
											root.SetAttribute("width", "200");
											root.SetAttribute("height", "150");
											doc.Save(destinationFile);
										}
									}
								}
							}

							XsltArgumentList args = new XsltArgumentList();
							args.AddParam("svgUrl",
								"",
								destinationPath);
							xslt.Transform(iterator.Current.Clone(), args, resultXmlWriter);
						}

						resultXmlWriter.Flush();

						String result = resultStringWriter.ToString();
						webBrowser1.DocumentText = result;
					}
				}
			}
			catch (System.Exception exception)
			{
				webBrowser1.DocumentText = exception.ToString();
			}

		}

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
		private void ShowRequestButton_Click(object sender, EventArgs e)
		{
			try
			{
				int productModelID = int.Parse(ProductModelIDTextBox.Text,
					CultureInfo.InvariantCulture);
				TransformAndBrowseDocument(GetSoapRequestXml(productModelID));
			}
			catch (System.Exception exception)
			{
				webBrowser1.DocumentText = exception.ToString();
			}
		}

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
		private void ShowResponseButton_Click(object sender, EventArgs e)
		{
			try
			{
				int productModelID = int.Parse(ProductModelIDTextBox.Text,
					CultureInfo.InvariantCulture);
				String requestXML = GetSoapRequestXml(productModelID);
				using (Stream webResponseStream = PostSoapRequest(requestXML))
				{

					XPathDocument xmlResults = new XPathDocument(webResponseStream);
					TransformAndBrowseDocument(xmlResults);
				}
			}
			catch (System.Exception exception)
			{
				webBrowser1.DocumentText = exception.ToString();
			}
		}

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
		private void ShowXSLButton_Click(object sender, EventArgs e)
		{
			try
			{
				using (StreamReader fs = File.OpenText(instructionsXsltFileName))
				{
					TransformAndBrowseDocument(fs.ReadToEnd());
				}
			}
			catch (System.Exception exception)
			{
				webBrowser1.DocumentText = exception.ToString();
			}
		}

		private void TransformAndBrowseDocument(String xmlDocument)
		{
			using (StringReader sr = new StringReader(xmlDocument))
			{
				using (XmlTextReader xtr = new XmlTextReader(sr))
				{
					XPathDocument doc = new XPathDocument(xtr);
					TransformAndBrowseDocument(doc);
				}
			}
		}

		private void TransformAndBrowseDocument(XPathDocument doc)
		{
			XslCompiledTransform xslt = new XslCompiledTransform();
			using (StreamReader xsltStreamReader = File.OpenText(prettyXmlXsltFileName))
			{
				using (XmlReader xsltXmlReader = XmlReader.Create(xsltStreamReader))
				{
					xslt.Load(xsltXmlReader);
				}
			}

			StringWriter resultStringWriter = new StringWriter(CultureInfo.InvariantCulture);
			XmlTextWriter resultXmlWriter = new XmlTextWriter(resultStringWriter);

			try
			{
				xslt.Transform(doc, new XsltArgumentList(), resultXmlWriter);
				resultXmlWriter.Flush();
			}
			finally
			{
				resultXmlWriter.Close();
			}

			webBrowser1.DocumentText = resultStringWriter.ToString();
		}

	}
}